package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.domain.CourseType;
import cn.itsource.ymcc.mapper.CourseTypeMapper;
import cn.itsource.ymcc.result.JSONResult;
import cn.itsource.ymcc.service.ICourseTypeService;
import cn.itsource.ymcc.util.AssertUtil;
import cn.itsource.ymcc.vo.CourseTypeCrumbsVo;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author whale
 * @since 2021-09-12
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {



    //通过注册来删除缓存
    @CacheEvict(cacheNames = "course_type",key = "'all'")
    @Override
    public boolean insert(CourseType entity) {
        boolean success = super.insert(entity);

        //2.删除缓存
        //redisTemplate.delete(BaseConstants.RedisConstants.KEY_COURSE_TYPE_ALL);

        return success;
    }

    //通过注册来删除缓存
    @CacheEvict(cacheNames = "course_type",key = "'all'")
    @Override
    public boolean deleteById(Serializable id) {
        boolean success = super.deleteById(id);
        //2.删除缓存
        //redisTemplate.delete(BaseConstants.RedisConstants.KEY_COURSE_TYPE_ALL);

        return success;
    }

    //通过注册来删除缓存
    @CacheEvict(cacheNames = "course_type",key = "'all'")
    @Override
    public boolean updateById(CourseType entity) {
        boolean success =  super.updateById(entity);
        //2.删除缓存
        //redisTemplate.delete(BaseConstants.RedisConstants.KEY_COURSE_TYPE_ALL);

        return success;
    }


    @Cacheable(cacheNames = "course_type",key = "'all'")
    public JSONResult treeData(){
        List<CourseType> allCourseType = selectList(null);
        return list2Tree(allCourseType);
    }

    public JSONResult list2Tree(List<CourseType> allCourseType ) {
        //查询所有分类

        //把所有分类存储到一个hashmap中
        HashMap<Long,CourseType> allCourseTypeMaps = new HashMap<>(allCourseType.size());
        for(CourseType courseType : allCourseType){
            allCourseTypeMaps.put(courseType.getId(), courseType);
        }

        //装一级分类
        List<CourseType> firstCourseType = new ArrayList<>();
        for (CourseType courseType : allCourseType) {

            //查找一级分类
            if(courseType.getPid() == null || courseType.getPid().longValue() == 0){
                firstCourseType.add(courseType);
            }else{
                CourseType parentType = allCourseTypeMaps.get(courseType.getPid());
                if(parentType != null){
                    parentType.getChildren().add(courseType);
                }
            }
        }

        return JSONResult.success(firstCourseType);
    }


    /**-----------------------------------------------------------------
     * Description：查询面包屑
     * 1.校验参数
     * 2.根据当前课程分类ID查询课程分类
     * 3.得到课程分类的path ->  1037.1039.1040
     * 4.通过“ .” 分割path,得到多个分类的id集合，而且是上上级，上级，当前级的顺序 [1037  , 1039 , 1040]
     * 5.批量查询出多个分类对象  [courseType  , courseType , courseType]
     * 6.需要把   [courseType  , courseType , courseType] 变成
     *           [CourseTypeCrumbsVo ，CourseTypeCrumbsVo ，CourseTypeCrumbsVo]
     *   循环分类，每次循环 ，创建一个vo对象，把当前分类装到 vo.ownerCourseType
     *   为当前分类查询同级分类列表，装到vo.otherCourseTypes
     *-----------------------------------------------------------------*/
    @Override
    public List<CourseTypeCrumbsVo> courseTypeIdCrumbs(Long courseTypeId) {
        //* 1.校验参数
        AssertUtil.isNotNull(courseTypeId,"无效的ID" );
        //* 2.根据当前课程分类ID查询课程分类
        CourseType currentCourseType = super.selectById(courseTypeId);

        //* 3.得到课程分类的path ->  1037.1039.1040
        String path = currentCourseType.getPath();

        //* 4.通过“ .” 分割path,得到多个分类的id集合，而且是上上级，上级，当前级的顺序 [1037  , 1039 , 1040]
        String[] idsStr = path.split("\\.");

        //* 5.批量查询出多个分类对象  [courseType  , courseType , courseType]
        List<CourseType> courseTypes = super.selectBatchIds(Arrays.asList(idsStr));

        //* 6.需要把   [courseType  , courseType , courseType] 变成
        //*           [CourseTypeCrumbsVo ，CourseTypeCrumbsVo ，CourseTypeCrumbsVo]

        //结果
        List<CourseTypeCrumbsVo> result = new ArrayList<>(courseTypes.size());

        courseTypes.forEach(courseType ->{
            //循环分类，每次循环 ，创建一个vo对象，
            CourseTypeCrumbsVo vo = new CourseTypeCrumbsVo();

            //*   把当前分类装到 vo.ownerCourseType
            vo.setOwnerCourseType(courseType);

            //*   为当前分类查询同级分类列表，装到vo.otherCourseTypes

            Wrapper<CourseType> wrapper = new EntityWrapper<>();
            wrapper.eq("pid", courseType.getPid());

            List<CourseType> others = baseMapper.selectList(wrapper);

            others.remove(courseType);

            vo.setOtherCourseTypes(others);
            //添加到结果集
            result.add(vo);
        });

        return result;
    }

}
